package service

import (
	"errors"
	"fmt"
	"go.uber.org/zap"
	"niu-video/app/consts"
	"niu-video/app/model"
	"niu-video/app/repository"
	"niu-video/pkg/hash"
	"niu-video/pkg/jwt"
	"niu-video/pkg/logger"
	"niu-video/pkg/redis"
)

var UserService = newUserService()

func newUserService() *userService {
	return &userService{}
}

type userService struct {
}

func (u *userService) Register(request model.RegisterRequest) error {
	if request.PasswordConfirm != request.PasswordConfirm {
		return errors.New("确认密码与密码不一致！")
	}
	user := repository.UserRepository.GetBy("username", request.Username)
	if user.UserID != 0 {
		return errors.New("该用户名已存在！")
	}
	err := repository.UserRepository.Save(&model.User{
		Username: request.Username,
		Password: hash.BcryptHash(request.Password),
		Nickname: request.Username,
	})
	if err != nil {
		logger.Error("user", zap.String("create", "用户创建失败！"))
		return errors.New("用户注册失败！")
	}
	return nil
}

func (u *userService) Login(request model.LoginRequest) (string, error) {
	user := repository.UserRepository.GetBy("username", request.Username)
	if user.UserID == 0 || !hash.BcryptCheck(request.Password, user.Password) {
		return "", errors.New("用户名或密码错误！")
	}
	token := jwt.NewJWT().IssueToken(user.UserID, user.Username)
	return token, nil
}

func (u *userService) Info(userId int64) (model.Author, error) {
	user := repository.UserRepository.Get(userId)
	if user.UserID == 0 {
		return model.Author{}, errors.New("用户不存在！")
	}
	isFollow := false
	if userId != 0 {
		isFollow = RelationService.IsFollow(userId, userId)
	}
	author := model.Author{
		UserId:   userId,
		IsFollow: isFollow,
		Username: user.Username,
		Avatar:   user.Avatar,
		Nickname: user.Nickname,
	}
	return author, nil
}

func (u *userService) Reset(request model.ResetRequest) (string, error) {
	user := repository.UserRepository.GetBy("username", request.Username)
	if user.UserID == 0 || !hash.BcryptCheck(request.Password, user.Password) {
		return "", errors.New("用户名或密码错误！")
	}
	user.Password = hash.BcryptHash(request.NewPassword)
	err := repository.UserRepository.Save(&user)
	if err != nil {
		logger.Error("user", zap.String("create", "用户修改失败！"))
		return "", errors.New("修改密码失败！")
	}
	return "密码修改成功！", nil
}

func (u *userService) Get(userId int64, selfUserId int64) (model.AuthorVo, error) {
	user := repository.UserRepository.Get(userId)
	if user.UserID == 0 {
		return model.AuthorVo{}, errors.New("用户不存在！")
	}
	isFollow := false
	if userId != 0 {
		isFollow = RelationService.IsFollow(userId, selfUserId)
	}
	author := model.AuthorVo{
		FollowCount:   user.FollowCount, // 关注人数
		FollowerCount: RelationService.RelationCount(userId),
		WorkerCount:   repository.VideoRepository.VideoCountByUserId(userId),
		UserId:        userId,
		IsFollow:      isFollow,
		Username:      user.Username,
		Avatar:        user.Avatar,
		Nickname:      user.Nickname,
		Signature:     user.Signature,
	}
	// 如果是自己就可以看点赞数和收藏
	if userId == selfUserId {
		author.LikeCount = repository.LikeRepository.LikeCountByUserId(userId)
		author.CollectCount = repository.CollectRepository.CollectCountByUserId(userId)
	}
	return author, nil
}

func (u *userService) Update(request model.UpdateUserInfoRequest, userId int64) error {
	if err := repository.UserRepository.UpdateUser(request, userId); err != nil {
		return errors.New("修改失败！")
	}
	return nil
}

func (u *userService) UserAction(request model.UserAction, userId int64) {
	//producer := new(kafka.Producer)
	//producer.InitProducer(consts.KAFKA_USER_ACTION)
	//producer.SendMessage(fmt.Sprintf("%d %d %f", userId, request.VideoId, request.Ratio))

	uv := repository.UserVideoRatioRepository.GetUserUserVideoRatio(request.VideoId, userId)
	uv.UserID = userId
	uv.VideoID = request.VideoId
	uv.Ratio += request.Ratio
	repository.UserVideoRatioRepository.Save(&uv)

	// redis 去重用户看过的video
	redis.Redis.SAdd(fmt.Sprintf("%s:%d", consts.REDIS_USER_VIEW_PREFIX, userId), request.VideoId)
}
